<script lang="ts" setup>
  import { onMounted, ref, watch, h } from 'vue'
  import { useCodeScanSetService } from '../../services/codeScanSet'
  import { ElDivider, ElMessage, UploadRawFile } from 'element-plus'
  import { CodeScanSet, CodeScanSetData } from '../../types'
  import _ from 'lodash'
  import ButtonGroup from './compontnets/ButtonGroup.vue'
  import BaseOption from './compontnets/BaseOption.vue'
  import GoodImg from './compontnets/GoodImg.vue'
  import ProductInfo from './compontnets/ProductInfo.vue'
  import SecurityCoding from './compontnets/SecurityCoding.vue'
  import GoodCodeInfo from './compontnets/GoodCodeInfo.vue'
  import CodeRegisterFieldParam from './compontnets/CodeRegisterFieldParam.vue'
  import AddText from './compontnets/AddText.vue'
  import AddImg from './compontnets/AddImg.vue'
  import AddVideo from './compontnets/AddVideo.vue'
  import { codeUpload, deleteFile } from '@/api/upload'

  const emits = defineEmits<{
    (e: 'getForm', value: Array<CodeScanSet>): void
  }>()

  // 间距组件的间隔符
  const spacer = h(ElDivider, {
    direction: 'vertical',
    style: 'display: flex; align-items: center;',
  })

  // 使用服务
  const { get, codeScanSets, getLoading, save } = useCodeScanSetService()

  // 用于将设置恢复成原来的样子
  const defaultSet = ref<Array<CodeScanSet>>([])

  // 左侧图标文件
  const logoFile = ref<UploadRawFile | null>(null)

  // 图标更新事件
  const handleLogoUpdate = (file: UploadRawFile) => {
    logoFile.value = file
  }

  // 左侧图标删除事件
  const handleLogoDel = () => {
    logoFile.value = null
  }

  // 更新设置事件
  const handleUpdate = (index: number, param: Array<CodeScanSetData>) => {
    codeScanSets.value[index].data = param
  }

  // 图片保存的位置
  const imageSave = ref<Array<{ index: number; setItemIndex: number; file: UploadRawFile }>>([])

  // 图片更新事件
  const handleImageUpdate = (index: number, setItemIndex: number, file: UploadRawFile) => {
    imageSave.value.push({ index, setItemIndex, file: file })
    codeScanSets.value[index].data[setItemIndex].val = URL.createObjectURL(file)
  }

  // 删除新增的图片
  const handleDeleteNewImage = (index: number, setItemIndex: number) => {
    codeScanSets.value[index].data[setItemIndex].val = ''
    const __imageSave = _.clone(imageSave.value)
    imageSave.value.length = 0
    __imageSave.forEach((image) => {
      if (image.index !== index || image.setItemIndex !== setItemIndex) {
        imageSave.value.push(image)
      }
    })
  }

  // 移除新增的设置
  const handleRemoveNewSet = (index: number) => {
    codeScanSets.value.splice(index, 1)
  }

  // 上移
  const handleMoveUp = (index: number) => {
    const current = codeScanSets.value.splice(index, 1)[0]
    codeScanSets.value.splice(index - 1, 0, current)
  }

  // 下移
  const handleMoveDown = (index: number) => {
    const current = codeScanSets.value.splice(index, 1)[0]
    codeScanSets.value.splice(index + 1, 0, current)
  }

  // 添加设置事件
  const handleAddFeild = (param: 1 | 2 | 3) => {
    const _data = {
      type: 9,
      fieldType: param,
      data: [
        {
          dataType: 0,
          align: 1,
          name: '',
          val: '',
          show: true,
        },
      ],
    }
    // 如果是图片或视频最多只能添加10个
    if (param === 2 || param === 3) {
      let i = 0
      codeScanSets.value.forEach((set) => {
        if (set.type === 9 && set.fieldType === param) {
          i += 1
        }
      })
      if (i >= 10) {
        ElMessage({
          type: 'warning',
          message: `最多只能新增10个${param === 2 ? '图片' : '视频'}选项`,
        })
        return
      }
      codeScanSets.value.push(_data)
      return false
    }
    // 如果是文字就无限制的添加
    codeScanSets.value.push(_data)
  }

  // 产品信息实例
  const productInfoRef = ref<InstanceType<typeof ProductInfo>[] | null>(null)

  // 设置恢复为默认
  const handleDefault = () => {
    codeScanSets.value = _.cloneDeep(defaultSet.value)
    if (productInfoRef.value) {
      productInfoRef.value.forEach((ele) => {
        ele.restoreDefault()
      })
    }
  }

  // 获取设置并设置默认值
  const getDataAndSetDefault = () => {
    get().then(() => {
      defaultSet.value = _.cloneDeep(codeScanSets.value)
    })
  }

  // 保存事件
  const handleSave = async () => {
    if (logoFile.value) {
      // 上传logo前先将之前的logo删除
      const baseOption = defaultSet.value.find((item) => item.type === 1)
      const logo = baseOption.data.find((item) => item.dataType === 3)
      if (logo.val) {
        await deleteFile([logo.val])
      }

      // 上传新的logo
      const res = await codeUpload([logoFile.value])

      // 保存薪logo的url
      codeScanSets.value.forEach((set) => {
        if (set.type === 1) {
          set.data.forEach((setItem) => {
            if (setItem.dataType === 3) {
              setItem.val = res.data.data.rows[0]
            }
          })
        }
      })
    }
    for (const item of imageSave.value) {
      // 上传图片前先将之前的图片删除
      const oldUrl = defaultSet.value[item.index].data[item.setItemIndex].val
      if (oldUrl) {
        await deleteFile([oldUrl])
      }

      // 上传新的图片
      const res = await codeUpload([item.file])

      // 保存图片新的url
      codeScanSets.value[item.index].data[item.setItemIndex].val = res.data.data.rows[0]
    }

    // 更新设置
    const res = await save()

    // 更新默认设置
    getDataAndSetDefault()

    ElMessage({
      type: res.code === 20000 ? 'success' : 'error',
      message: res.message,
      showClose: true,
      duration: 5000,
      plain: true,
    })
  }

  watch(codeScanSets, (value) => {
    emits('getForm', value)
  })

  onMounted(() => {
    getDataAndSetDefault()
  })
</script>

<template>
  <div>
    <div class="btn_group">
      <ButtonGroup
        :codeScanSets="codeScanSets"
        @addField="handleAddFeild"
        @default="handleDefault"
        @save="handleSave"
      />
    </div>
    <el-scrollbar v-loading="getLoading" height="76vh">
      <div class="set">
        <el-collapse>
          <template v-for="(set, index) in codeScanSets" :key="set.type">
            <!--基础选项-->
            <el-collapse-item v-if="set.type === 1" name="basic_options" title="基础选项">
              <div style="margin-left: 1.4vw">
                <BaseOption
                  :sets="set.data"
                  @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"
                  @logo-update="handleLogoUpdate"
                  @logo-del="() => handleLogoDel"
                />
              </div>
            </el-collapse-item>

            <!--产品图片-->
            <el-collapse-item v-else-if="set.type === 2" name="product_image" title="产品图片">
              <template v-for="setItem in set.data" :key="setItem.name">
                <div style="margin-left: 1.4vw">
                  <el-card shadow="never">
                    <GoodImg v-model="setItem.show" />
                  </el-card>
                </div>
              </template>
            </el-collapse-item>

            <!--产品信息-->
            <el-collapse-item v-else-if="set.type === 3" name="product_info">
              <template #title>
                <div style="display: flex; align-items: center">
                  <span style="margin-right: 12px">产品信息</span>
                  <el-space :size="0" :spacer="spacer">
                    <HLink
                      v-if="index > 2"
                      @focus="(e) => e.target.blur()"
                      @click.stop="handleMoveUp(index)"
                      >上移
                    </HLink>
                    <HLink v-if="true" @click.stop="handleMoveDown(index)">下移 </HLink>
                  </el-space>
                </div>
              </template>
              <div style="margin-left: 1.4vw">
                <ProductInfo
                  ref="productInfoRef"
                  :sets="set.data"
                  @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"
                />
              </div>
            </el-collapse-item>

            <!--防伪条码-->
            <el-collapse-item v-else-if="set.type === 4" name="code">
              <template #title>
                <div style="display: flex; align-items: center">
                  <span style="margin-right: 12px">防伪条码</span>
                  <el-space :size="0" :spacer="spacer">
                    <HLink
                      v-if="index > 2"
                      @focus="(e) => e.target.blur()"
                      @click.stop="handleMoveUp(index)"
                      >上移
                    </HLink>
                    <HLink
                      v-if="index < codeScanSets.length - 1"
                      link
                      @click.stop="handleMoveDown(index)"
                      >下移
                    </HLink>
                  </el-space>
                </div>
              </template>
              <div style="margin-left: 1.4vw">
                <SecurityCoding
                  :sets="set.data"
                  @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"
                />
              </div>
            </el-collapse-item>

            <!--产品编号信息-->
            <el-collapse-item v-else-if="set.type === 5" name="product_code_info">
              <template #title>
                <div style="display: flex; align-items: center">
                  <span style="margin-right: 12px">产品编号信息</span>
                  <el-space :size="0" :spacer="spacer">
                    <HLink
                      v-if="index > 2"
                      @focus="(e) => e.target.blur()"
                      @click.stop="handleMoveUp(index)"
                      >上移
                    </HLink>
                    <HLink
                      v-if="index < codeScanSets.length - 1"
                      @click.stop="handleMoveDown(index)"
                      >下移
                    </HLink>
                  </el-space>
                </div>
              </template>
              <div style="margin-left: 1.4vw">
                <GoodCodeInfo
                  :sets="set.data"
                  @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"
                />
              </div>
            </el-collapse-item>

            <!--产品编号登记信息-->
            <el-collapse-item v-else-if="set.type === 6" name="product_code_register_info">
              <template #title>
                <div style="display: flex; align-items: center">
                  <span style="margin-right: 12px">产品编号登记信息</span>
                  <el-space :size="0" :spacer="spacer">
                    <HLink
                      v-if="index > 2"
                      @focus="(e) => e.target.blur()"
                      @click.stop="handleMoveUp(index)"
                      >上移
                    </HLink>
                    <HLink
                      v-if="index < codeScanSets.length - 1"
                      link
                      @click.stop="handleMoveDown(index)"
                      >下移
                    </HLink>
                  </el-space>
                </div>
              </template>
              <div style="margin-left: 1.4vw">
                <CodeRegisterFieldParam
                  :sets="set.data"
                  @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"
                />
              </div>
            </el-collapse-item>

            <!--条码登记字段参数-->
            <el-collapse-item v-else-if="set.type === 7" name="code_register_field_param">
              <template #title>
                <div style="display: flex; align-items: center">
                  <span style="margin-right: 12px">条码登记字段参数</span>
                  <el-space :size="0" :spacer="spacer">
                    <HLink
                      v-if="index > 2"
                      @focus="(e) => e.target.blur()"
                      @click.stop="handleMoveUp(index)"
                      >上移
                    </HLink>
                    <HLink
                      v-if="index < codeScanSets.length - 1"
                      @click.stop="handleMoveDown(index)"
                      >下移
                    </HLink>
                  </el-space>
                </div>
              </template>
              <div style="margin-left: 1.4vw">
                <CodeRegisterFieldParam
                  :sets="set.data"
                  @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"
                />
              </div>
            </el-collapse-item>

            <!--产品简介与参数说明-->
            <!--<el-collapse-item v-else-if="set.type === 8" name="product_profile_param_explain">-->
            <!--  <template #title>-->
            <!--    <div style="display: flex; align-items: center">-->
            <!--      <span style="margin-right: 12px">产品简介与参数说明</span>-->
            <!--      <el-button-->
            <!--        v-if="index > 2"-->
            <!--        link-->
            <!--        type="primary"-->
            <!--        @focus="(e) => e.target.blur()"-->
            <!--        @click.stop="handleMoveUp(index)"-->
            <!--        >上移-->
            <!--      </el-button>-->
            <!--      <el-button-->
            <!--        v-if="index < codeScanSets.length - 1"-->
            <!--        link-->
            <!--        style="margin: 0"-->
            <!--        type="primary"-->
            <!--        @click.stop="handleMoveDown(index)"-->
            <!--        >下移-->
            <!--      </el-button>-->
            <!--    </div>-->
            <!--  </template>-->
            <!--  <div style="margin-left: 1.4vw">-->
            <!--    <ProductProfileParamExplain-->
            <!--      :sets="set.data"-->
            <!--      @update="(param: Array<CodeScanSetData>) => handleUpdate(index, param)"-->
            <!--    />-->
            <!--  </div>-->
            <!--</el-collapse-item>-->

            <template v-else>
              <!--新增文字-->
              <template v-if="set.fieldType === 1">
                <template v-for="(setItem, setItemIndex) in set.data" :key="setItemIndex">
                  <el-collapse-item>
                    <template #title>
                      <div
                        style="
                          display: flex;
                          align-items: center;
                          gap: 5px;
                          justify-content: flex-end;
                        "
                      >
                        <span>新增文字</span>
                        <el-space :size="0" :spacer="spacer">
                          <HLink
                            v-if="index > 2"
                            @focus="(e) => e.target.blur()"
                            @click.stop="handleMoveUp(index)"
                            >上移
                          </HLink>
                          <HLink
                            v-if="index < codeScanSets.length - 1"
                            @click.stop="handleMoveDown(index)"
                            >下移
                          </HLink>
                          <HLink type="error" @click.stop="handleRemoveNewSet(index)">删除</HLink>
                        </el-space>
                      </div>
                    </template>
                    <div style="margin-left: 1.4vw">
                      <AddText
                        :set="setItem"
                        @update="(param: CodeScanSetData) => codeScanSets[index].data[setItemIndex] = param"
                      />
                    </div>
                  </el-collapse-item>
                </template>
              </template>

              <!--上传图片-->
              <template v-else-if="set.fieldType === 2">
                <template v-for="(setItem, setItemIndex) in set.data" :key="setItemIndex">
                  <el-collapse-item>
                    <template #title>
                      <div
                        style="
                          display: flex;
                          align-items: center;
                          gap: 5px;
                          justify-content: flex-end;
                        "
                      >
                        <span>新增图片</span>
                        <el-space :size="0" :spacer="spacer">
                          <HLink
                            v-if="index > 2"
                            @focus="(e) => e.target.blur()"
                            @click.stop="handleMoveUp(index)"
                            >上移
                          </HLink>
                          <HLink
                            v-if="index < codeScanSets.length - 1"
                            @click.stop="handleMoveDown(index)"
                            >下移
                          </HLink>
                          <HLink type="error" @click.stop="handleRemoveNewSet(index)">删除</HLink>
                        </el-space>
                      </div>
                    </template>
                    <div style="margin-left: 1.4vw">
                      <AddImg
                        :set="setItem"
                        @update="(param: CodeScanSetData) => codeScanSets[index].data[setItemIndex] = param"
                        @img-update="(file: UploadRawFile) => handleImageUpdate(index, setItemIndex, file)"
                        @img-del="handleDeleteNewImage(index, setItemIndex)"
                      />
                    </div>
                  </el-collapse-item>
                </template>
              </template>

              <!--上传视频-->
              <template v-else>
                <template v-for="(setItem, setItemIndex) in set.data" :key="setItemIndex">
                  <el-collapse-item>
                    <template #title>
                      <div
                        style="
                          display: flex;
                          align-items: center;
                          gap: 5px;
                          justify-content: flex-end;
                        "
                      >
                        <span>新增视频</span>
                        <el-space :size="0" :spacer="spacer">
                          <HLink
                            v-if="index > 2"
                            @focus="(e) => e.target.blur()"
                            @click.stop="handleMoveUp(index)"
                            >上移
                          </HLink>
                          <HLink
                            v-if="index < codeScanSets.length - 1"
                            @click.stop="handleMoveDown(index)"
                            >下移
                          </HLink>
                          <HLink type="error" @click.stop="handleRemoveNewSet(index)">删除</HLink>
                        </el-space>
                      </div>
                    </template>
                    <div style="margin-left: 1.4vw">
                      <AddVideo
                        :set="setItem"
                        @update="(param: CodeScanSetData) => codeScanSets[index].data[setItemIndex] = param"
                      />
                    </div>
                  </el-collapse-item>
                </template>
              </template>
            </template>
          </template>
        </el-collapse>
      </div>
    </el-scrollbar>
  </div>
</template>

<style lang="scss" scoped>
  :deep(.el-textarea__inner) {
    border-radius: 2px !important;
  }

  :deep(.el-card__body) {
    padding: 8px;
  }

  .mt-10 {
    margin-bottom: 10px;
  }

  .flex-center-5 {
    display: flex;
    align-items: center;
    gap: 5px;
  }

  .set_container {
    .btn_group {
      display: flex;
      justify-content: flex-end;
      margin-bottom: 10px;
    }

    .set {
      width: 26vw;
      margin: 16px;
    }
  }
</style>
